package com.atlin.project.controller;

import com.atlin.project.annotation.AuthCheck;
import com.atlin.project.common.BaseResponse;
import com.atlin.project.common.DeleteRequest;
import com.atlin.project.common.ErrorCode;
import com.atlin.project.common.ResultUtils;
import com.atlin.project.contant.UserConstant;
import com.atlin.project.exception.BusinessException;
import com.atlin.project.exception.ThrowUtils;
import com.atlin.project.model.domain.QuotationData;
import com.atlin.project.model.domain.QuotationStatistics;
import com.atlin.project.model.domain.User;
import com.atlin.project.model.dto.quotationData.*;
import com.atlin.project.model.vo.QuotationDataRecommendVO;
import com.atlin.project.model.vo.QuotationDataVO;
import com.atlin.project.service.QuotationDataService;
import com.atlin.project.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 语录数据接口
 *
 * @author atlin
 */
@RestController
@RequestMapping("/quotation_data")
public class QuotationDataController {

    @Resource
    private QuotationDataService quotationDataService;

    @Resource
    private UserService userService;

    private final static Gson GSON = new Gson();

    // region 增删改查

    /**
     * 创建
     *
     * @param quotationDataAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addQuotationData(@RequestBody QuotationDataAddRequest quotationDataAddRequest, HttpServletRequest request) {
        if (quotationDataAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QuotationData quotationData = new QuotationData();
        BeanUtils.copyProperties(quotationDataAddRequest, quotationData);
        quotationDataService.validQuotationData(quotationData, true);

        quotationData.setDataLength(quotationData.getContent().length());

        boolean result = quotationDataService.save(quotationData);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        long newQuotationDataId = quotationData.getId();
        return ResultUtils.success(newQuotationDataId);
    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteQuotationData(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        QuotationData oldQuotationData = quotationDataService.getById(id);
        ThrowUtils.throwIf(oldQuotationData == null, ErrorCode.NULL_ERROR);

        boolean b = quotationDataService.removeById(id);
        return ResultUtils.success(b);
    }

    /**
     * 更新（仅管理员）
     *
     * @param quotationDataUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateQuotationData(@RequestBody QuotationDataUpdateRequest quotationDataUpdateRequest) {
        if (quotationDataUpdateRequest == null || quotationDataUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QuotationData quotationData = new QuotationData();
        BeanUtils.copyProperties(quotationDataUpdateRequest, quotationData);

        // 参数校验
        quotationDataService.validQuotationData(quotationData, false);
        long id = quotationDataUpdateRequest.getId();
        // 判断是否存在
        QuotationData oldQuotationData = quotationDataService.getById(id);
        ThrowUtils.throwIf(oldQuotationData == null, ErrorCode.NULL_ERROR);

        quotationData.setDataLength(quotationData.getContent().length());

        boolean result = quotationDataService.updateById(quotationData);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<QuotationData> getQuotationDataById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QuotationData quotationData = quotationDataService.getById(id);
        if (quotationData == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        return ResultUtils.success(quotationData);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<QuotationDataVO> getQuotationDataVOById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QuotationData quotationData = quotationDataService.getById(id);
        if (quotationData == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }

        QuotationDataVO quotationDataVO = QuotationDataVO.objToVo(quotationData);
        return ResultUtils.success(quotationDataVO);
    }

    /**
     * 分页获取列表（封装类）
     *
     * @param quotationDataQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<QuotationDataVO>> listQuotationDataVOByPage(@RequestBody QuotationDataQueryRequest quotationDataQueryRequest,
                                                                         HttpServletRequest request) {
        long current = quotationDataQueryRequest.getCurrent();
        long size = quotationDataQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<QuotationData> quotationDataPage = quotationDataService.page(new Page<>(current, size),
                new QueryWrapper<>());

        Page<QuotationDataVO> quotationDataVOPage = quotationDataService.getQuotationDataVOPage(quotationDataPage, request);

        return ResultUtils.success(quotationDataVOPage);
    }

    /**
     * 分页获目列表（仅管理员）
     *
     * @param quotationDataQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<QuotationData>> listQuotationDataByPage(@RequestBody QuotationDataQueryRequest quotationDataQueryRequest,
                                                                     HttpServletRequest request) {
        long current = quotationDataQueryRequest.getCurrent();
        long size = quotationDataQueryRequest.getPageSize();
        Page<QuotationData> quotationDataPage = quotationDataService.page(new Page<>(current, size),
                quotationDataService.getQueryWrapper(quotationDataQueryRequest));
        return ResultUtils.success(quotationDataPage);
    }

    // endregion

    /**
     * 手动抓取语录数据
     * 仅管理员使用
     *
     * @param request 请求
     * @return 结果
     */
    @GetMapping("/quotation/capture_quote")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> captureQuote(HttpServletRequest request) {
//        quotationDataService.captureQuoteData();

        // 异步执行此任务 耗时 大约 ** 55s ** 
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            quotationDataService.captureQuoteData();
        });

        return ResultUtils.success(true);
    }

    /**
     * 手动抓取语录数据
     * 仅管理员使用
     *
     * @param request 请求
     * @return 结果
     */
    @PostMapping("/quotation/capture_quote")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> captureQuote(@RequestBody QuotationDataCaptureRequest quotationDataCaptureRequest,HttpServletRequest request) {
        if (quotationDataCaptureRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        quotationDataService.captureQuoteData(quotationDataCaptureRequest);
        // 异步执行此任务 耗时 大约 ** 55s ** 
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            quotationDataService.captureQuoteData();
        });

        return ResultUtils.success(true);
    }

    /**
     * 语录每日推荐
     * 支持手动刷新
     *
     * @param quotationDataRecommendQuery 推荐查询条件
     * @param request                     请求 -- 需要登录
     * @return 推荐语录
     */
    @PostMapping("/quotation/recommend")
    public BaseResponse<QuotationDataRecommendVO> getQuotationRecommend(@RequestBody QuotationDataRecommendQuery quotationDataRecommendQuery,
                                                                        HttpServletRequest request) {

        QuotationDataRecommendVO quotationDataRecommendVO = quotationDataService.quotationRecommend(quotationDataRecommendQuery, request);
        return ResultUtils.success(quotationDataRecommendVO);
    }

    /**
     * 语录数据统计分析
     *
     * @param quotationDataRecommendQuery
     * @param request
     * @return
     */
    @PostMapping("/quotation/statistics")
    public BaseResponse<QuotationStatistics> getQuotationStatistics(@RequestBody QuotationStatisticsQuery quotationDataRecommendQuery,
                                                                    HttpServletRequest request) {

        return ResultUtils.success(quotationDataService.getQuotationStatistics(quotationDataRecommendQuery));
    }

    /**
     * 语录来源详细
     * @param fromAddrList
     * @param request
     * @return
     */
    @PostMapping("/quotation/fromAddrDetail")
    public BaseResponse<List<QuotationDataVO>> getFromAddrDetail(@RequestBody List<String> fromAddrList,
                                                                    HttpServletRequest request) {
        ThrowUtils.throwIf(CollectionUtils.isEmpty(fromAddrList),ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(quotationDataService.getFromAddrDetail(fromAddrList));
    }

    /**
     * 语录来源者详细
     * @param fromWhoList
     * @param request
     * @return
     */
    @PostMapping("/quotation/fromWhoDetail")
    public BaseResponse<List<QuotationDataVO>> getFromWhoDetail(@RequestBody List<String> fromWhoList,
                                                                 HttpServletRequest request) {
        ThrowUtils.throwIf(CollectionUtils.isEmpty(fromWhoList),ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(quotationDataService.getFromWhoDetail(fromWhoList));
    }

}
